// --------------------------------------------------------------------------------------------------------------------
// <copyright file="SettingsFileTreeNode.cs" company="Roman '4ux-nbIx' Novitsky">
//   Copyright (c) Roman '4ux-nbIx' Novitsky 2009
// </copyright>
// <summary>
//   Describes and manipulates the settings file tree node.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace SettingsManager
{
  #region Namespace Imports

  using System;
  using System.Globalization;
  using System.Linq;
  using System.Runtime.Serialization;
  using System.Windows.Forms;

  using ComponentSettingsManagers;

  using JetBrains.Annotations;

  #endregion


  /// <summary>
  /// Describes and manipulates the settings file tree node.
  /// </summary>
  [Serializable]
  internal sealed class SettingsFileTreeNode : TreeNode
  {
    #region Constructors and Destructors

    /// <summary>
    /// Initializes a new instance of the <see cref="SettingsFileTreeNode"/> class.
    /// </summary>
    /// <param name="settingsFile">
    /// The settings file.
    /// </param>
    public SettingsFileTreeNode([NotNull] SettingsFile settingsFile)
    {
      Text = GetText(settingsFile);

      int imageIndex = GetImageIndex(settingsFile);
      ImageIndex = imageIndex;
      SelectedImageIndex = imageIndex;
      StateImageIndex = imageIndex;

      Tag = settingsFile;

      CreateInfoNodes(settingsFile);
    }


    /// <summary>
    /// Initializes a new instance of the <see cref="SettingsFileTreeNode"/> class.
    /// </summary>
    /// <param name="serializationInfo">
    /// A <see cref="T:System.Runtime.Serialization.SerializationInfo"/> containing the data to deserialize the class.
    /// </param>
    /// <param name="context">
    /// The <see cref="T:System.Runtime.Serialization.StreamingContext"/> containing the source and destination of the serialized stream.
    /// </param>
    [UsedImplicitly]
    public SettingsFileTreeNode([NotNull] SerializationInfo serializationInfo, StreamingContext context)
      : base(serializationInfo, context)
    {
    }

    #endregion


    #region Methods

    private static int GetImageIndex([NotNull] SettingsFile settingsFile)
    {
      var sharedSettingsFile = settingsFile as SharedSettingsFile;

      if (sharedSettingsFile != null)
      {
        return sharedSettingsFile.IsGlobal ? 1 : 4;
      }

      return 4;
    }


    private static string GetText([NotNull] SettingsFile settingsFile)
    {
      return settingsFile.DisplayName;
    }


    private void CreateInfoNodes([NotNull] SettingsFile settingsFile)
    {
      string text = string.Format(CultureInfo.InvariantCulture, "Path: {0}", settingsFile.Path.FullPath);

      CreateInformationNode(text, settingsFile);

      text = string.Format(
        CultureInfo.InvariantCulture, "Update common R# settings: {0}", settingsFile.AutoUpdateCommonSettings);

      CreateInformationNode(text, settingsFile);

      string resharperSettingsLocation = settingsFile.ExternalSettingsContainerFilePath == null
                                           ? "stored inside the file." : "stored externally.";

      text = string.Format(CultureInfo.InvariantCulture, "R# settings location: {0}", resharperSettingsLocation);

      TreeNode treeNode = CreateInformationNode(text, settingsFile);

      if (settingsFile.ExternalSettingsContainerFilePath != null)
      {
        resharperSettingsLocation = settingsFile.ExternalSettingsContainerFilePath.FullPath;

        if (!settingsFile.ExternalSettingsContainerFilePath.IsAbsolute)
        {
          resharperSettingsLocation = string.Format(
            "{0} ({1})", resharperSettingsLocation, settingsFile.ExternalSettingsContainerAbsoluteFilePath.FullPath);
        }

        text = string.Format(CultureInfo.InvariantCulture, "Path: {0}", resharperSettingsLocation);
        CreateInformationNode(text, settingsFile, treeNode);
      }

      treeNode = CreateInformationNode("Stored settings", settingsFile);

      var sharedSettingsFile = settingsFile as SharedSettingsFile;

      foreach (IComponentSettingsManager manager in ResharperSettingsManager.Instance.ComponentSettingsManagers.OrderBy(m => m.Name))
      {
        bool isLoaded = settingsFile.SettingsManagers.Contains(manager);
        int imageIndex = isLoaded ? 6 : 7;

        text = manager.Name;

        if (sharedSettingsFile != null)
        {
          SharedSettingsFile parent = sharedSettingsFile.ParentSettingsFile;

          while (parent != null)
          {
            if (parent.SettingsManagers.Contains(manager))
            {
              break;
            }

            parent = parent.ParentSettingsFile;
          }

          if (parent != null)
          {
            if (isLoaded)
            {
              text += string.Format(CultureInfo.InvariantCulture, " (Overrides '{0}' settings)", GetText(parent));
            }
            else
            {
              text += string.Format(CultureInfo.InvariantCulture, " (Inherits '{0}' settings)", GetText(parent));
            }
          }
        }

        CreateInformationNode(text, settingsFile, treeNode, imageIndex);
      }
    }


    [NotNull]
    private TreeNode CreateInformationNode([NotNull] string text, SettingsFile settingsFile, [NotNull] TreeNode parentNode = null, int imageIndex = 5)
    {
      var node = new TreeNode(text, imageIndex, imageIndex) { Tag = settingsFile };

      if (parentNode == null)
      {
        parentNode = this;
      }

      parentNode.Nodes.Add(node);

      return node;
    }

    #endregion
  }
}